//============================================================================
// Name        : ListItr.h
// Author      : bycy
// Version     : 1.0
// Description : 
//============================================================================

#include <iostream>
#include "AbsListItr.h"

template < class Type > class ListItr : public AbsListItr < Type > {

private:

	ListNode< Type > * const head;
	ListNode< Type > * Current;

public:

	ListItr(const List< Type > & L) : head(L.head){
	
		Current = L.isEmpty() ? head : head->Next;

	}

	/* 
	* Deconstruct an ListItr
	* 
	* REQUIRE:
	*	
	* RETURN:	
	*
	* NOTES:	
	*/

	~ListItr(){}

	/* 
	* Look for an elment in this ListItr
	* 
	* REQUIRE:	x NOT NULL
	*	
	* RETURN:	index if this ListItr contains x
	*		-1 if this ListItr does not contain x
	*
	* NOTES:	
	*/

	int Find(const Type & x);

	int IsFound(const Type & x) const;

	/* 
	* Insert an elment into this ListItr
	* 
	* REQUIRE:	x NOT NULL
	*	
	* RETURN:	
	*
	* NOTES:	
	*/

	void Insert(const Type & x);

	/* 
	* Remove an elment from this ListItr
	* 
	* REQUIRE:	x NOT NULL
	*	
	* RETURN:	index if this ListItr contains x
	*		-1 if this AbsListItr does not contain x
	*
	* NOTES:	
	*/

	int Remove(const Type & x);

	int operator + () const{
	
		return Current && Current != head;

	}

	const Type & operator()() const;

	void operator ++ ();

	void operator ++ (int){
	
		operator ++();

	}

	void Zeroth(){ Current = head;}

	void First();

	const ListItr & operator = (const ListItr &);

	void Exception(int Condition,const char* ErrorMsg){
	
		if(Condition){
			cerr << ErrorMsg << endl;
			abort();
		}

	}

};


/* 
	* Insert an elment into this ListItr
	* 
	* REQUIRE:	x NOT NULL
	*	
	* RETURN:	
	*
	* NOTES:	
	*/

template < class Type >
void ListItr < Type > ::Insert(const Type &x){

	Exception(Current == NULL,"The location is illegal!");
	ListNode < Type > *p;
	p = new ListNode < Type > (x,Current->Next);
	Current = Current->Next = p;

}

/* 
	* Look for an elment in this ListItr
	* 
	* REQUIRE:	x NOT NULL
	*	
	* RETURN:	index if this ListItr contains x
	*		-1 if this ListItr does not contain x
	*
	* NOTES:	
	*/

template < class Type > 
int ListItr < Type > ::Find(const Type &x){

	ListNode < Type > * Ptr = head->Next;
	while(Ptr != NULL && !(Ptr->data == x))
		Ptr = Ptr->Next;
	if(Ptr == NULL) 
		return 0;
	Current = Ptr;
	return 1;

}

template < class Type >
int ListItr < Type > :: IsFound(const Type &x) const{

	ListNode < Type > *Ptr = head->Next;
	while(Ptr != NULL && !(Ptr->data == x))
		Ptr = Ptr->Next;
	return Ptr!= NULL;

}

/* 
	* Remove an elment from this ListItr
	* 
	* REQUIRE:	x NOT NULL
	*	
	* RETURN:	index if this ListItr contains x
	*		-1 if this AbsListItr does not contain x
	*
	* NOTES:	
	*/

template < class Type >
int ListItr< Type > ::Remove(const Type &x){

	ListNode < Type > *Ptr = head;
	while(Ptr->Next != NULL && !(Ptr->Next->data ==x))
		Ptr = Ptr->Next;
	if(Ptr->Next ==NULL)
		return 0;
	ListNode< Type > *P = Ptr->Next;
	Ptr->Next = Ptr->Next->Next;
	delete P;
	Current = head;
	return 1;

}

template < class Type >
const Type & ListItr< Type > ::operator ()() const{

	Exception(Current == head,"The location is not correct!");
	return Current->data;

}

template < class Type >
void ListItr < Type > ::operator ++(){

	Exception(Current == NULL,"There is not next node!");
	Current = Current->Next;

}

template < class Type >
const ListItr< Type > & ListItr < Type > ::operator =(const ListItr<Type> & R){

	if(this == &R)
		return *this;
	Exception(head != R.head,"Reference to another list, it is ERROR!");
	Current = R.Current;
	return *this;

}

template < class Type > 
void ListItr < Type > ::First(){

	Exception(head->Next == NULL,"There is not first node");
	Current = head->Next;

}